<!--主页页面-->
<template style="height: 1500px; overflow: auto">
  <el-container
    direction="vertical"
    v-infinite-scroll="loadMoreQuestions"
    :infinite-scroll-disabled="busy"
    :infinite-scroll-delay="800"
    :infinite-scroll-distance="5"
    style="min-height: 100%; background-color: #f6f6f6"
  >
    <!--    头部内容 START-->
    <el-affix>
      <MainHeader @change="handleTypeChange" @add="handleQuestionAdd" />
    </el-affix>
    <!--    头部内容 END-->

    <el-container class="main-container">
      <!--    侧栏内容 START-->
      <el-affix target=".main-container" :offset="61" z-index="30">
        <el-aside>
          <MainAside ref="asideComp" />
        </el-aside>
      </el-affix>
      <!--    侧栏内容 END-->

      <el-container style="width: 750px">
        <!--    主要内容 START-->
        <el-main style="">
          <el-card>
            <el-tabs
              v-model="currentTab"
              class="question-wrapper"
              @tab-change="orderTypeChange"
            >
              <el-tab-pane label="最新" name="latest" />
              <el-tab-pane label="热门" name="hot" />
            </el-tabs>
            <!--          问题展示 START-->
            <el-empty
              v-if="
                !questionLoading &&
                (questions == null || questions.length === 0)
              "
              description="暂无问题"
            />
            <div
              class="question-box"
              v-for="(question, q_index) in questions"
              :key="q_index"
              v-else
            >
              <el-divider v-if="q_index > 0" />
              <!--            问题内容 START-->
              <div class="question-content">
                <h3
                  style="cursor: pointer; width: fit-content"
                  @click="toQuestionDetail(question)"
                >
                  {{ question.question_title }}
                </h3>
                <el-text truncated>{{ question.question_content }}</el-text>
              </div>
              <!--            问题内容 END-->

              <!--            问题信息 START-->
              <div class="question-info">
                <el-button
                  :type="question._liked ? 'warning' : 'primary'"
                  :icon="Star"
                  @click="questionLike(q_index)"
                >
                  好问题 {{ question.liked_count }}
                </el-button>
                <el-button
                  :icon="ChatRound"
                  @click="commentsShowOrHide(q_index)"
                  link
                  >{{
                    showComment.index === q_index && showComment.flag
                      ? "收起评论"
                      : "查看评论"
                  }}</el-button
                >
                <el-dropdown trigger="click" style="margin-left: 15px">
                  <el-button :icon="Share" type="primary" plain>分享</el-button>
                  <template #dropdown>
                    <el-dropdown-item :icon="Link" @click="copyLink(q_index)">
                      分享链接
                    </el-dropdown-item>
                  </template>
                </el-dropdown>
                <el-text type="info" style="margin-left: 15px">{{
                  question.create_time
                }}</el-text>
              </div>
              <!--            问题信息 START-->
              <div
                class="question-comments"
                v-if="showComment.index === q_index && showComment.flag"
              >
                <!--            输入评论 START-->
                <div style="display: flex; gap: 15px">
                  <el-input
                    v-model="commentTextArea"
                    type="textarea"
                    placeholder="请输入评论内容"
                    maxlength="512"
                    resize="none"
                    autosize
                  />
                  <el-button
                    type="primary"
                    @click="
                      commentCommit(
                        commentTextArea,
                        question.question_id,
                        null,
                        comments
                      )
                    "
                  >
                    发布
                  </el-button>
                </div>
                <!--            输入评论 END-->

                <!--            问题评论 START-->
                <el-skeleton
                  :loading="commentLoading[q_index]"
                  style="--el-skeleton-circle-size: 40px; margin-top: 15px"
                  animated
                >
                  <template #template>
                    <div
                      style="
                        display: flex;
                        gap: 15px;
                        margin-bottom: 10px;
                        align-items: center;
                      "
                    >
                      <el-skeleton-item variant="circle" />
                      <el-skeleton-item variant="h3" style="width: 20%" />
                    </div>
                    <el-skeleton-item variant="text" style="width: 60%" />
                  </template>
                  <template #default>
                    <!--            评论内容 START-->
                    <div>
                      <el-card shadow="Never">
                        <template #header>
                          <el-text size="large">{{
                            comments == null || comments.length === 0
                              ? "暂无评论"
                              : `共${comments.length}条评论`
                          }}</el-text>
                        </template>
                        <el-empty
                          v-if="comments == null || comments.length === 0"
                          description="暂无评论"
                        >
                        </el-empty>
                        <div v-for="(comment, c_index) in comments" v-else>
                          <div class="question-comment-user">
                            <div
                              style="
                                display: flex;
                                gap: 10px;
                                align-items: center;
                              "
                            >
                              <el-avatar
                                :src="
                                  avatarError.get(comment.comment_id)
                                    ? '//images.weserv.nl/?url=150.158.52.191:8080/HeadPortrait/default?t=' +
                                      Math.random()
                                    : '//images.weserv.nl/?url=150.158.52.191:8080/HeadPortrait/' +
                                      comment.user_id +
                                      '?t=' +
                                      Math.random()
                                "
                                @error="
                                  avatarError.set(
                                    comment.comment_id,
                                    !avatarError.get(comment.comment_id)
                                  )
                                "
                                style="cursor: pointer"
                                @click="asideComp.toUser(comment.user_id)"
                              />
                              <h3
                                class="question-comment-user-name"
                                style="cursor: pointer"
                                @click="asideComp.toUser(comment.user_id)"
                              >
                                {{ comment.username }}
                              </h3>
                              <el-tag
                                type="primary"
                                size="small"
                                v-if="comment.user_id === question.user_id"
                              >
                                作者
                              </el-tag>
                            </div>
                            <el-button
                              :icon="CaretTop"
                              style="text-align: right"
                              :type="comment.liked ? 'danger' : 'primary'"
                              size="large"
                              @click="commentLike(comment)"
                              link
                            >
                              {{ comment.liked_count }}
                            </el-button>
                          </div>
                          <div class="question-comment-content">
                            <el-text size="large">{{
                              comment.comment_content
                            }}</el-text>
                            <div>
                              <el-button
                                :icon="Delete"
                                type="danger"
                                v-if="comment.user_id === refUserId"
                                @click="
                                  deleteComment(
                                    c_index,
                                    null,
                                    comment.comment_id
                                  )
                                "
                                link
                              >
                                删除评论
                              </el-button>
                              <el-button
                                type="info"
                                :icon="ChatRound"
                                @click="responseShowOrHide(q_index, c_index)"
                                link
                              >
                                回复
                              </el-button>
                            </div>
                          </div>
                          <div
                            style="
                              display: flex;
                              gap: 15px;
                              margin-bottom: 10px;
                            "
                            v-if="
                              showResponse.q_index === q_index &&
                              showResponse.c_index === c_index &&
                              showResponse.flag
                            "
                          >
                            <el-input
                              v-model="responseTextAreas[c_index]"
                              type="textarea"
                              :placeholder="'回复: ' + comment.username"
                              maxlength="512"
                              resize="none"
                              autosize
                            />
                            <el-button
                              type="primary"
                              @click="
                                commentCommit(
                                  responseTextAreas[c_index],
                                  comment.comment_id,
                                  comment.comment_id,
                                  comment.responses
                                )
                              "
                              plain
                            >
                              回复
                            </el-button>
                          </div>
                          <div
                            v-if="
                              comment.responses != null &&
                              comment.responses.length > 0
                            "
                            style="padding-left: 30px"
                          >
                            <div
                              v-for="(response, r_index) in comment.responses"
                            >
                              <div class="question-comment-user">
                                <div
                                  style="
                                    display: flex;
                                    gap: 10px;
                                    align-items: center;
                                  "
                                >
                                  <el-avatar
                                    :src="
                                      avatarError.get(response.comment_id)
                                        ? '//images.weserv.nl/?url=150.158.52.191:8080/HeadPortrait/default?t=' +
                                          Math.random()
                                        : '//images.weserv.nl/?url=150.158.52.191:8080/HeadPortrait/' +
                                          response.user_id +
                                          '?t=' +
                                          Math.random()
                                    "
                                    @error="
                                      avatarError.set(
                                        response.comment_id,
                                        !avatarError.get(response.comment_id)
                                      )
                                    "
                                    style="cursor: pointer"
                                    @click="asideComp.toUser(comment.user_id)"
                                  />
                                  <h3
                                    class="question-comment-user-name"
                                    style="cursor: pointer"
                                    @click="asideComp.toUser(comment.user_id)"
                                  >
                                    {{ response.username }}
                                  </h3>
                                  <el-tag
                                    type="primary"
                                    size="small"
                                    v-if="response.user_id === question.user_id"
                                  >
                                    作者
                                  </el-tag>
                                </div>
                                <el-button
                                  :icon="CaretTop"
                                  :type="response.liked ? 'danger' : 'primary'"
                                  style="text-align: right"
                                  size="large"
                                  @click="commentLike(response)"
                                  link
                                  >{{ response.liked_count }}</el-button
                                >
                              </div>
                              <div class="question-comment-content">
                                <el-text size="large">{{
                                  response.comment_content
                                }}</el-text>
                                <el-button
                                  :icon="Delete"
                                  type="danger"
                                  v-if="response.user_id === refUserId"
                                  @click="
                                    deleteComment(
                                      c_index,
                                      r_index,
                                      response.comment_id
                                    )
                                  "
                                  link
                                >
                                  删除评论
                                </el-button>
                              </div>
                            </div>
                          </div>
                          <div
                            style="height: 15px"
                            v-if="c_index + 1 < comments.length"
                          />
                        </div>
                      </el-card>
                    </div>
                    <!--            评论内容 END-->
                  </template>
                </el-skeleton>
              </div>
              <!--            问题评论 END-->
            </div>
            <!--            问题展示 END-->
            <el-skeleton :loading="questionLoading" animated>
              <template #template>
                <div
                  style="
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                    margin: 5px 0;
                    padding: 10px 0;
                  "
                >
                  <el-skeleton-item variant="h3" style="width: 25%" />
                  <el-skeleton-item variant="text" />
                  <el-skeleton-item variant="text" style="width: 60%" />
                </div>
              </template>
            </el-skeleton>
          </el-card>
        </el-main>
        <!--    主要内容END-->
      </el-container>
    </el-container>
  </el-container>
</template>

<script setup>
import { ref } from "vue";
import {
  Star,
  Share,
  ChatRound,
  Delete,
  Link,
  CaretTop,
} from "@element-plus/icons-vue";
import MainHeader from "@/components/common/MainHeader.vue";
import MainAside from "@/components/common/MainAside.vue";
import useClipboard from "vue-clipboard3";
import axios from "axios";
import { ElMessageBox, ElNotification } from "element-plus";
import { useRouter } from "vue-router";

const { toClipboard } = useClipboard();
const asideComp = ref(null);
const router = useRouter();
const BASE_URL = "http://localhost:8080",
  LIMIT = 10;

const userId = JSON.parse(localStorage.getItem("user")).id,
  refUserId = ref(parseInt(userId));

/* --------------------------- 主页问题展示 --------------------------- */

const busy = ref(true),
  questionLoading = ref(true),
  commentLoading = ref([]),
  currentTab = ref("latest"),
  questions = ref([]);

let maxLens = {
  default: 20,
  follow: 20,
};

getQuestions(
  BASE_URL + "/question/list?user_id=-1",
  0,
  20,
  (resp) => {
    questionLoading.value = false;
    if (resp.status === 0) {
      questions.value = resp.data;
      commentLoading.value = new Array(questions.value.length).fill(false);
      if (questions.value.length >= 20) busy.value = false;
    } else {
      ElNotification.error("问题加载失败，请检查网络连接是否正常");
    }
  },
  (error) => {
    console.log(error.request);
    questionLoading.value = false;
    ElNotification.error("问题加载失败，请检查网络连接是否正常");
  }
);

function getQuestions(baseUrl, start, limit = LIMIT, success, error) {
  axios
    .get(
      `${baseUrl}&current_id=${userId}&start=${start}&limit=${limit}&order_type=latest`
    )
    .then((r) => {
      success(r.data);
    })
    .catch((e) => {
      error(e);
      console.log(e.request.response);
      ElNotification.error("问题加载失败，请检查网络连接是否正常");
    });
}

function loadMoreQuestions(limit = LIMIT) {
  if (router.currentRoute.value.name !== "mainPage") return;

  if (questions.value.length === 0) return;
  if (!questionLoading.value) {
    questionLoading.value = true;
    getQuestions(
      BASE_URL + "/question/list?user_id=-1",
      questions.value.length,
      limit,
      (resp) => {
        questionLoading.value = false;
        if (resp.status === 0) {
          if (resp.data.length === 0) {
            ElNotification.info("没有更多问题了");
            return;
          }
          questions.value = questions.value.concat(resp.data);
          commentLoading.value = commentLoading.value.concat(
            new Array(limit).fill(false)
          );
        } else {
          ElNotification.error("问题加载失败，请检查网络连接是否正常");
        }
      },
      () => {
        questionLoading.value = false;
      }
    );
  }
}

const handleTypeChange = (types) => {
  showComment.value.flag = false;
  questionLoading.value = true;
  maxLens[types.last] = Math.max(maxLens[types.last], questions.value.length);
  switch (types.current) {
    case "default":
      getQuestions(
        `${BASE_URL}/question/list?user_id=-1`,
        0,
        maxLens["default"],
        (resp) => {
          questionLoading.value = false;
          questions.value = resp.data;
          if (questions.value.length >= maxLens["default"]) busy.value = false;
        },
        () => {
          questionLoading.value = false;
        }
      );
      break;
    case "follow":
      getQuestions(
        `${BASE_URL}/question/list?user_id=${userId}`,
        0,
        maxLens["follow"],
        (resp) => {
          questionLoading.value = false;
          questions.value = resp.data;
          if (questions.value.length >= maxLens["follow"]) busy.value = false;
        },
        () => {
          questionLoading.value = false;
        }
      );
      break;
  }
};

const handleQuestionAdd = (que) => {
  if (questions.value == null) questions.value = new Array(1).fill(que);
  else questions.value.push(que);
};

const orderTypeChange = () => {
  showComment.value.flag = false;
  const type = currentTab.value;
  switch (type) {
    case "latest": {
      questions.value.sort(
        (a, b) => Date.parse(b.create_time) - Date.parse(a.create_time)
      );
      break;
    }
    case "hot": {
      questions.value.sort((a, b) => b.liked_count - a.liked_count);
      break;
    }
  }
};

const toQuestionDetail = (question) => {
  let page = router.resolve({
    path: "/QuestionDetail",
    query: {
      question_id: question.question_id,
    },
  });
  window.open(page.href, "_blank");
};

/* --------------------------- 评论展示 --------------------------- */
const showComment = ref({
    flag: false,
    index: 0,
  }),
  showResponse = ref({
    flag: false,
    q_index: 0,
    c_index: 0,
  }),
  responseTextAreas = ref([]),
  commentTextArea = ref(""),
  comments = ref([]),
  avatarError = ref(undefined);

function commentsShowOrHide(index) {
  showComment.value.flag ^= true;
  if (index !== showComment.value.index) {
    showComment.value.index = index;
    showComment.value.flag = true;
  }
  if (showComment.value) getComments(index);
}

function getComments(index) {
  commentLoading.value[index] = true;
  axios
    .get(
      `${BASE_URL}/comment/like/desc?to_id=${questions.value[index].question_id}&type=0&from_id=${userId}`
    )
    .then((r) => {
      commentLoading.value[index] = false;
      const resp = r.data;
      if (resp.status === 0) {
        comments.value = resp.data;
        avatarError.value = new Map();
        comments.value.forEach((comment) => {
          avatarError.value.set(comment.comment_id, false);
          comment.responses.forEach((response) => {
            avatarError.value.set(response.comment_id, false);
          });
        });
        responseTextAreas.value = new Array(comments.value.length).fill("");
      } else {
        ElNotification.error("评论加载失败，请检查网络连接是否正常");
      }
    })
    .catch((error) => {
      console.log(error.request.response);
      commentLoading.value[index] = false;
      ElNotification.error("访问服务器失败，请检查网络连接是否正常");
    });
}

function responseShowOrHide(q_index, c_index) {
  showResponse.value.flag ^= true;
  if (
    q_index !== showResponse.value.q_index ||
    c_index !== showResponse.value.c_index
  ) {
    showResponse.value = {
      q_index: q_index,
      c_index: c_index,
      flag: true,
    };
  }
}

function commentLike(comment) {
  const id = comment.comment_id;
  comment.liked ^= true;
  comment.liked_count += comment.liked ? 1 : -1;
  if (comment.liked) {
    axios
      .patch(`http://localhost:8080/comment/like?comment_id=${id}&user_id=1`)
      .then((resp) => {
        if (resp.data.status !== 0) {
          comment.liked = false;
          comment.liked_count--;
          ElNotification.error("点赞失败，请检查网络连接是否正常");
        }
      })
      .catch((error) => {
        comment.liked = false;
        comment.liked_count--;
        console.log(error.request.response);
        ElNotification.error("点赞失败，请检查网络连接是否正常");
      });
  } else {
    axios
      .patch(
        `http://localhost:8080/comment/like/cancel?comment_id=${id}&user_id=1`
      )
      .then((resp) => {
        if (resp.data.status !== 0) {
          comment.liked = true;
          comment.liked_count++;
          ElNotification.error("取消点赞失败，请检查网络连接是否正常");
        }
      })
      .catch((error) => {
        comment.liked = true;
        comment.liked_count++;
        console.log(error.request.response);
        ElNotification.error("取消点赞失败，请检查网络连接是否正常");
      });
  }
}

const deleteComment = (c_index, r_index, id) => {
  ElMessageBox.confirm("是否确认删除这条评论？", "删除评论", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      axios
        .delete(`http://localhost:8080/comment?comment_id=${id}`)
        .then((r) => {
          const resp = r.data;
          if (resp.status === 0) {
            if (r_index == null) comments.value.splice(c_index, 1);
            else comments.value[c_index].responses.splice(r_index, 1);
          } else {
            ElNotification.error("删除失败，请检查网络连接是否正常");
          }
        })
        .catch((error) => {
          console.log(error.request);
          ElNotification.error("删除失败，请检查网络连接是否正常");
        });
    })
    .catch(() => {});
};

const commentCommit = (textarea, to_id, at_id, curComments) => {
  const INFO = textarea.trim();
  if (INFO == null || INFO === "") {
    ElNotification.warning("评论信息不能为空");
    return;
  }
  axios
    .post(
      "http://localhost:8080/comment",
      JSON.stringify({
        comment_content: INFO,
        type: 0,
        user_id: userId,
        to_id: to_id,
        at_comment_id: at_id,
      }),
      {
        headers: {
          "Content-Type": "application/json",
        },
      }
    )
    .then((r) => {
      const resp = r.data;
      if (resp.status === 0) {
        if (curComments == null) curComments = new Array(1).fill(resp.data);
        else curComments.push(resp.data);
        ElNotification.success("评论成功");
      } else {
        ElNotification.error("评论失败，请检查网络连接是否正常");
      }
    })
    .catch((error) => {
      console.log(error);
      ElNotification.error("评论失败，请检查网络连接是否正常");
    });
};

/* --------------------------- 分享链接 --------------------------- */
const copyLink = async (index) => {
  try {
    await toClipboard(
      `http://localhost:3900/#/QuestionDetail?question_id=${questions.value[index]["question_id"]}`
    );
    ElNotification.success("分享链接已复制到剪切板");
  } catch (e) {
    await ElMessageBox.alert(
      "分享链接",
      `http://localhost:3900/#/QuestionDetail?question_id=${questions[index]["question_id"]}`
    );
  }
};

/* --------------------------- 好问题 --------------------------- */
const questionLike = (index) => {
  const que = questions.value[index];
  que.liked_count += que._liked ? -1 : 1;
  que._liked ^= true;
  if (que._liked) {
    axios
      .patch(
        `http://localhost:8080/question/like?question_id=${que.question_id}&user_id=${userId}`
      )
      .then((r) => {
        const resp = r.data;
        if (resp.status === 0) {
        } else {
          que._liked ^= true;
          que.liked_count--;
          ElNotification.error("操作失败，请检查网络连接是否正常");
        }
      })
      .catch((error) => {
        que._liked ^= true;
        que.liked_count--;
        console.log(error.request.response);
        ElNotification.error("操作失败，请检查网络连接是否正常");
      });
  } else {
    axios
      .delete(
        `http://localhost:8080/question/like?question_id=${que.question_id}&user_id=${userId}`
      )
      .then((r) => {
        const resp = r.data;
        if (resp.status === 0) {
        } else {
          que._liked ^= true;
          que.liked_count++;
          ElNotification.error("操作失败，请检查网络连接是否正常");
        }
      })
      .catch((error) => {
        que._liked ^= true;
        que.liked_count++;
        console.log(error.request.response);
        ElNotification.error("操作失败，请检查网络连接是否正常");
      });
  }
};
</script>

<style scoped>
.main-container {
  width: 1100px;
  margin: auto;
}
.question-box {
  text-align: left;
}
.question-content {
  margin-bottom: 15px;
}
.question-info {
}
.question-comments {
}
.question-comments > div {
  margin: 10px 0;
}
.question-comment-user,
.question-comment-content {
  display: flex;
  margin-bottom: 10px;
  justify-content: space-between;
  align-items: center;
}
.question-comment-user-name {
  margin: auto 0;
}
</style>
